extends Node

# 对话打断信号
signal request_aborted(service_name: String)

# 服务配置字典
var service_config := {
	"ollama": {
		"endpoint": "http://localhost:11434/api/generate",
		"headers": {"Content-Type": "application/json"}
	}
}

# 请求参数模板
var request_templates := {
	"ollama": {
		"model": "qwen3:1.7b",
		"prompt": "请使用中文进行回复，避免使用任何 Markdown 格式。希望你的回答尽量像真实的人类对话一样自然流畅，采用日常口语化的表达方式，符合人们在聊天时的习惯。请根据你想要强调的部分，合理使用 <b> 标签进行替换且不要使用**来强调，但不要使用代码块或复杂的排版结构。",
		"stream": false
	}
}

var current_request: HTTPRequest = null
var is_aborting = false

# 发送对话请求
func request_dialogue(
	service_name: String,
	prompt: String,
	callback: Callable,
	context: Array = [],
	options: Dictionary = {}
) -> void:
	
	print("已收到请求 " + service_name + " " + prompt)	
	# 如果已有请求在进行，先中断
	if current_request:
		abort_request()
	
	# 重置中断标志
	is_aborting = false
	
	# 验证服务是否存在
	if not service_config.has(service_name):
		push_error("Service not configured: " + service_name)
		callback.call({
			"success": false,
			"error": "Service not configured"
		})
		return

	# 创建HTTP请求
	current_request = HTTPRequest.new()
	add_child(current_request)
	current_request.set_meta("service", service_name)  # 保存服务名称用于后续处理
	current_request.request_completed.connect(_on_request_completed.bind(current_request, callback))

	# 准备请求数据
	var config = service_config[service_name]
	var template = request_templates.get(service_name, {})
	var payload = _build_payload(service_name, prompt + template["prompt"], context, options, template)
	
	# 将headers字典转换为PackedStringArray
	var headers_array: PackedStringArray = []
	for key in config.headers:
		headers_array.append("%s: %s" % [key, config.headers[key]])

	# 发送请求
	var error = current_request.request(
		config.endpoint,
		headers_array,  # 使用转换后的headers数组
		HTTPClient.METHOD_POST,
		JSON.stringify(payload)
		)
		
	if error != OK:
		callback.call({
			"success": false,
			"error": "HTTP request failed: " + str(error)
		})
		_cleanup_request(current_request)
		current_request = null

# 中断当前请求
func abort_request() -> void:
	if current_request:
		is_aborting = true
		var service_name = current_request.get_meta("service")
		_cleanup_request(current_request)
		current_request = null
		emit_signal("request_aborted", service_name)

# 清理请求资源
func _cleanup_request(request: HTTPRequest) -> void:
	if is_instance_valid(request) and request.is_inside_tree():
		remove_child(request)
		request.queue_free()

# 构建服务特定的请求负载
func _build_payload(service: String, prompt: String, context: Array, options: Dictionary, template: Dictionary) -> Dictionary:
	var payload = template.duplicate(true)
	
	match service:
		"ollama":
			var full_prompt = "\n".join(context) + "\n" + prompt if context.size() > 0 else prompt
			payload["prompt"] = full_prompt
			payload.merge(options, true)
	return payload

# 处理请求完成回调
func _on_request_completed(result: int, response_code: int, headers: PackedStringArray, body: PackedByteArray, http_request: HTTPRequest, callback: Callable) -> void:
	# 检查请求是否已被中断
	if is_aborting or current_request != http_request:
		_cleanup_request(http_request)
		return

	# 获取服务名称
	var service_name = http_request.get_meta("service")
	
	# 清理请求节点
	_cleanup_request(http_request)
	current_request = null

	# 处理HTTP错误
	if result != HTTPRequest.RESULT_SUCCESS:
		callback.call({
			"success": false,
			"service": service_name,
			"error": "HTTP error: " + str(result),
			"response_code": response_code
		})
		return

	# 解析JSON响应
	var json = JSON.new()
	var body_text = body.get_string_from_utf8()
	var parse_error = json.parse(body_text)
	
	if parse_error != OK:
		callback.call({
			"success": false,
			"service": service_name,
			"error": "JSON parse error: " + json.get_error_message(),
			"raw_response": body_text
		})
		return

	# 处理服务特定响应
	var response_data = json.get_data()
	var processed = _process_response(response_data, service_name)
	
	# 返回统一格式
	callback.call({
		"success": true,
		"service": service_name,
		"response": processed,
		"raw": response_data
	})

# 处理不同服务的响应格式
func _process_response(data: Dictionary, service: String) -> String:
	match service:
		"ollama":
			return data.get("response", "").strip_edges()
	return "Unknown service response format"

# 添加/更新服务配置 (运行时)
func configure_service(service_name: String, endpoint: String, headers: Dictionary, template: Dictionary = {}) -> void:
	service_config[service_name] = {
		"endpoint": endpoint,
		"headers": headers
	}
	
	if not template.is_empty():
		request_templates[service_name] = template

# 设置API密钥
func set_api_key(service_name: String, api_key: String) -> void:
	if service_config.has(service_name):
		service_config[service_name]["headers"]["Authorization"] = "Bearer " + api_key
	else:
		push_error("Service not found: " + service_name)
